package com.googlecode.cswish.security;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.struts2.StrutsStatics;
import org.apache.struts2.views.util.ContextUtil;

import com.googlecode.cswish.security.auth.UserInfo;
import com.googlecode.cswish.struts.conversion.StrutsFreemarkerManager;
import com.googlecode.cswish.util.FrameConstant;
import com.googlecode.cswish.util.Functions;
import com.opensymphony.xwork2.util.ValueStack;

import freemarker.template.SimpleHash;
import freemarker.template.TemplateModelException;

/**
 * 
 * @see StrutsFreemarkerManager.buildTemplateModel
 * @see ContextUtil.getStandardContext
 * 
 * @author Jerry.Feng Date: 2008-6-6
 */
public class Context {
	
	private static final Logger logger = Logger.getLogger(Context.class);

	public static final String REQUEST_PARAMETER = "Parameters";
	public static final String USER = "user";
	public static final String MODEL = "model";
	
	private ValueStack stack;
	private Functions functions;
	
	private UserInfo user;
	private Object model;
	private Map inputParameter;
	private String fieldName;
	
	// more properties
	// pathId, field, condition name, old model object, etc
	
	private SimpleHash cache;
	
	public Context(ValueStack stack, Functions functions) {
		this.stack = stack;
		this.functions = functions;
	}

	public SimpleHash toTemplateModel() {
		SimpleHash templateModel;
		Map context = stack == null ? new HashMap() : stack.getContext();
		
		if (cache == null) {
			templateModel = cache = new SimpleHash();

			// 1. default input parameter
			Map param = (Map) context.get("parameters");
			SimpleHash defaultParam;
			if (param == null) {
				defaultParam = new SimpleHash();
			} else {
				defaultParam = new SimpleHash(param);
			}
			templateModel.put(REQUEST_PARAMETER, defaultParam);
			
			// 2. default user information
			HttpServletRequest request = (HttpServletRequest) context.get(StrutsStatics.HTTP_REQUEST);
			Object loginUser = SafeManager.getInstance().getLoginUser(request);
			if (logger.isDebugEnabled()) {
				if (loginUser == null) {
					logger.debug("Can't find the login user");
				}
			}
			templateModel.put(USER, loginUser);
		} else {
			templateModel = cache;
		}
		
		// initialize parameter
		if (inputParameter != null) {
			try {
				SimpleHash defaultParam = (SimpleHash) templateModel.get(REQUEST_PARAMETER);
				defaultParam.putAll(inputParameter);
			} catch (TemplateModelException ex) {
				logger.error("Can't update parameter information", ex);
			}
		}
		
		// initialize user information
		if (user != null) {
			templateModel.put(USER, user);
		}

		// 3. page information
		templateModel.put(FrameConstant.STACK_PAGEELEMENTS, context.get(FrameConstant.STACK_PAGEELEMENTS));
		templateModel.put(FrameConstant.SEC_CHECK_FIELD, fieldName);
		templateModel.put("model", model);
		templateModel.put("fn", functions);
		return templateModel;
	}

	public void setUserInfo(UserInfo user) {
		this.user = user;
	}
	
	public UserInfo getUserInfo() {
		return this.user;
	}

	public String getFieldName() {
		return fieldName;
	}

	public void setFieldName(String fieldName) {
		this.fieldName = fieldName;
	}

	public void addParamter(String name, String ... value) {
		if (inputParameter == null) {
			inputParameter = new HashMap();
		}
		inputParameter.put(name, value);
	}
	
	public String[] getParamter(String name) {
		if (inputParameter != null) {
			return (String[]) inputParameter.get(name);
		}
		return null;
	}

	public void setModel(Object model) {
		this.model = model;
	}
	
//	class NullAsBlankHash extends SimpleHash {
//		@Override
//		public TemplateModel get(String key) {
//			
//		}
//	}
}